module LZC_48bits (
	input  [ 47: 0]D            ,
	output         vld          ,
	output [  5: 0]leading_zeros   
	);
 
wire     [4*6 -1:0]PEnc8_x6 ;
wire     [5*3 -1:0]PEnc16_x3;
wire     [6*2 -1:0]PEnc32_0,PEnc32_1 ;
wire     [6     :0]PEnc48_0          ;
genvar   i ;
 
function [3:0]PEnc_8bits; //Priority Encoder: {vld,Q[2:0]}
input    [7:0]D;
reg           vld1;
begin
	vld1          = |D[7:4];
	PEnc_8bits[0] = vld1 ? D[7] | (~D[6] & D[5]) : D[3] | (~D[2] & D[1]) ; 
	PEnc_8bits[1] = vld1 ? D[7] | D[6]           : D[3] | D[2]           ;
	PEnc_8bits[2] = vld1                         ;
	PEnc_8bits[3] = vld1 | |D[3:0]               ;
end
endfunction
 
generate
for(i=0;i<6;i=i+1) begin: GEN0
	assign PEnc8_x6[i*4+3:i*4] = PEnc_8bits(D[i*8+7:i*8]);
end
endgenerate
 
generate
for(i=0;i<3;i=i+1) begin: GEN1
LZC_cascade #(
	.N(3)
)u_lzc16 (
	.Q1  ( PEnc8_x6[i*8+6:i*8+4] ),
	.Q0  ( PEnc8_x6[i*8+2:i*8+0] ),
	.vld1( PEnc8_x6[i*8+7]       ),
	.vld0( PEnc8_x6[i*8+3]       ),
	.Q   ( PEnc16_x3[ i*5+3:i*5+0] ),
	.vld ( PEnc16_x3[ i*5+4]       ) 
	);
end
endgenerate
 
LZC_cascade #(
	.N(4)
)u_lzc32 (
	.Q1  ( PEnc16_x3[8:    5] ),
	.Q0  ( PEnc16_x3[3:    0] ),
	.vld1( PEnc16_x3[9]       ),
	.vld0( PEnc16_x3[4]       ),
	.Q   ( PEnc32_0[ 4:    0] ),
	.vld ( PEnc32_0[ 5      ] ) 
	);
 
assign  PEnc32_1 = {PEnc16_x3[14],1'b0,PEnc16_x3[13:10]};
LZC_cascade #(
	.N(5)
)u_lzc48 (
	.Q1  ( PEnc32_1[4:    0] ),
	.Q0  ( PEnc32_0[4:    0] ),
	.vld1( PEnc32_1[5]       ),
	.vld0( PEnc32_0[5]       ),
	.Q   ( PEnc48_0[5:    0] ),
	.vld ( PEnc48_0[6      ] ) 
	);
assign  vld           =   PEnc48_0[6]  ;
assign  leading_zeros = {~PEnc32_1[5]&~PEnc32_0[4],PEnc48_0[4],~PEnc48_0[3:0]};
endmodule